home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / err.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-20  |  9.0 KB  |  442 lines

  1. /*
  2.  * Copyright (c) 1983 Eric P. Allman
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted provided
  7.  * that: (1) source distributions retain this entire copyright notice and
  8.  * comment, and (2) distributions including binaries display the following
  9.  * acknowledgement:  ``This product includes software developed by the
  10.  * University of California, Berkeley and its contributors'' in the
  11.  * documentation or other materials provided with the distribution and in
  12.  * all advertising materials mentioning features or use of this software.
  13.  * Neither the name of the University nor the names of its contributors may
  14.  * be used to endorse or promote products derived from this software without
  15.  * specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  17.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)err.c    5.10 (Berkeley) 6/1/90";
  23. static char  rcsid[] = "@(#)$Id: err.c,v 5.10.0.11 1991/06/21 12:47:57 paul Exp $";
  24. #endif /* not lint */
  25.  
  26. #include "sendmail.h"
  27. #include <errno.h>
  28. #include <netdb.h>
  29.  
  30. #ifdef __STDC__
  31. static void putmsg(const char *, int);
  32. static void puterrmsg(const char *);
  33. static void fmtmsg(char *, const char *, const char *, int, const char *, va_list);
  34. #else /* !__STDC__ */
  35. static void putmsg();
  36. static void puterrmsg();
  37. static void fmtmsg();
  38. #endif /* __STDC__ */
  39.  
  40. /*
  41. **  SYSERR -- Print error message.
  42. **
  43. **    Prints an error message via printf to the diagnostic
  44. **    output.  If LOG is defined, it logs it also.
  45. **
  46. **    Parameters:
  47. **        fmt -- the format string
  48. **        a, b, c, d, e -- parameters
  49. **
  50. **    Returns:
  51. **        none
  52. **        Through TopFrame if QuickAbort is set.
  53. **
  54. **    Side Effects:
  55. **        increments Errors.
  56. **        sets ExitStat.
  57. */
  58.  
  59. #ifdef lint
  60. int    sys_nerr;
  61. char    *sys_errlist[];
  62. #endif /* lint */
  63. char    MsgBuf[BUFSIZ*2];    /* text of most recent message */
  64.  
  65. /*VARARGS1*/
  66. #ifdef __STDC__
  67. void
  68. syserr(const char *fmt, ...)
  69. #else /* !__STDC__ */
  70. void
  71. syserr(fmt, va_alist)
  72.     const char *fmt;
  73. va_dcl
  74. #endif /* __STDC__ */
  75. {
  76.     va_list    args;
  77.     char *p;
  78.     int olderrno = errno;
  79.     extern char Arpa_PSyserr[];
  80.     extern char Arpa_TSyserr[];
  81.  
  82.     /* format and output the error message */
  83.     if (olderrno == 0)
  84.         p = Arpa_PSyserr;
  85.     else
  86.         p = Arpa_TSyserr;
  87. #ifdef __STDC__
  88.     va_start(args, fmt);
  89. #else /* !__STDC__ */
  90.     va_start(args);
  91. #endif /* __STDC__ */
  92.     fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, args);
  93.     va_end(args);
  94.     puterrmsg(MsgBuf);
  95.  
  96.     /* determine exit status if not already set */
  97.     if (ExitStat == EX_OK)
  98.     {
  99.         if (olderrno == 0)
  100.             ExitStat = EX_SOFTWARE;
  101.         else
  102.             ExitStat = EX_OSERR;
  103.     }
  104.  
  105. #ifdef LOG
  106.     if (LogLevel > 0)
  107.         syslog(LOG_CRIT, "%s: SYSERR: %s",
  108.             CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
  109.             &MsgBuf[4]);
  110. #endif /* LOG */
  111.     errno = 0;
  112.     if (QuickAbort)
  113.         longjmp(TopFrame, 2);
  114. }
  115. /*
  116. **  USRERR -- Signal user error.
  117. **
  118. **    This is much like syserr except it is for user errors.
  119. **
  120. **    Parameters:
  121. **        fmt, a, b, c, d -- printf strings
  122. **
  123. **    Returns:
  124. **        none
  125. **        Through TopFrame if QuickAbort is set.
  126. **
  127. **    Side Effects:
  128. **        increments Errors.
  129. */
  130.  
  131. /*VARARGS1*/
  132. #ifdef __STDC__
  133. void
  134. usrerr(const char *fmt, ...)
  135. #else /* !__STDC__ */
  136. void
  137. usrerr(fmt, va_alist)
  138.     const char *fmt;
  139. va_dcl
  140. #endif /* __STDC__ */
  141. {
  142.     va_list    args;
  143.     extern char Arpa_Usrerr[];
  144.     extern int errno;
  145.  
  146.     if (SuprErrs)
  147.         return;
  148.  
  149. #ifdef __STDC__
  150.     va_start(args, fmt);
  151. #else /* !__STDC__ */
  152.     va_start(args);
  153. #endif /* __STDC__ */
  154.     fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, errno, fmt, args);
  155.     va_end(args);
  156.     puterrmsg(MsgBuf);
  157.  
  158.     if (QuickAbort)
  159.         longjmp(TopFrame, 1);
  160. }
  161. /*
  162. **  MESSAGE -- print message (not necessarily an error)
  163. **
  164. **    Parameters:
  165. **        num -- the default ARPANET error number (in ascii)
  166. **        msg -- the message (printf fmt) -- if it begins
  167. **            with a digit, this number overrides num.
  168. **        a, b, c, d, e -- printf arguments
  169. **
  170. **    Returns:
  171. **        none
  172. **
  173. **    Side Effects:
  174. **        none.
  175. */
  176.  
  177. /*VARARGS2*/
  178. #ifdef __STDC__
  179. void
  180. message(const char *num, const char *msg, ...)
  181. #else /* !__STDC__ */
  182. void
  183. message(num, msg, va_alist)
  184.     const char *num;
  185.     const char *msg;
  186. va_dcl
  187. #endif /* __STDC__ */
  188. {
  189.     va_list    args;
  190.  
  191.     errno = 0;
  192. #ifdef __STDC__
  193.     va_start(args, msg);
  194. #else /* !__STDC__ */
  195.     va_start(args);
  196. #endif /* __STDC__ */
  197.     fmtmsg(MsgBuf, CurEnv->e_to, num, 0, msg, args);
  198.     va_end(args);
  199.     putmsg(MsgBuf, FALSE);
  200. }
  201. /*
  202. **  NMESSAGE -- print message (not necessarily an error)
  203. **
  204. **    Just like "message" except it never puts the to... tag on.
  205. **
  206. **    Parameters:
  207. **        num -- the default ARPANET error number (in ascii)
  208. **        msg -- the message (printf fmt) -- if it begins
  209. **            with three digits, this number overrides num.
  210. **        a, b, c, d, e -- printf arguments
  211. **
  212. **    Returns:
  213. **        none
  214. **
  215. **    Side Effects:
  216. **        none.
  217. */
  218.  
  219. /*VARARGS2*/
  220. #ifdef __STDC__
  221. void
  222. nmessage(const char *num, const char *msg, ...)
  223. #else /* !__STDC__ */
  224. void
  225. nmessage(num, msg, va_alist)
  226.     const char *num;
  227.     const char *msg;
  228. va_dcl
  229. #endif /* __STDC__ */
  230. {
  231.     va_list    args;
  232.  
  233.     errno = 0;
  234. #ifdef __STDC__
  235.     va_start(args, msg);
  236. #else /* !__STDC__ */
  237.     va_start(args);
  238. #endif /* __STDC__ */
  239.     fmtmsg(MsgBuf, (char *) NULL, num, 0, msg, args);
  240.     va_end(args);
  241.     putmsg(MsgBuf, FALSE);
  242. }
  243. /*
  244. **  PUTMSG -- output error message to transcript and channel
  245. **
  246. **    Parameters:
  247. **        msg -- message to output (in SMTP format).
  248. **        holdmsg -- if TRUE, don't output a copy of the message to
  249. **            our output channel.
  250. **
  251. **    Returns:
  252. **        none.
  253. **
  254. **    Side Effects:
  255. **        Outputs msg to the transcript.
  256. **        If appropriate, outputs it to the channel.
  257. **        Deletes SMTP reply code number as appropriate.
  258. */
  259.  
  260. static void
  261. putmsg(msg, holdmsg)
  262.     const char *msg;
  263.     bool holdmsg;
  264. {
  265.     /* output to transcript if serious */
  266.     if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
  267.         fprintf(CurEnv->e_xfp, "%s\n", msg);
  268.  
  269.     /* output to channel if appropriate */
  270.     if (!holdmsg && (Verbose || msg[0] != '0'))
  271.     {
  272.         (void) fflush(stdout);
  273.         if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
  274.             fprintf(OutChannel, "%s\r\n", msg);
  275.         else
  276.             fprintf(OutChannel, "%s\n", &msg[4]);
  277.         (void) fflush(OutChannel);
  278.     }
  279. }
  280. /*
  281. **  PUTERRMSG -- like putmsg, but does special processing for error messages
  282. **
  283. **    Parameters:
  284. **        msg -- the message to output.
  285. **
  286. **    Returns:
  287. **        none.
  288. **
  289. **    Side Effects:
  290. **        Sets the fatal error bit in the envelope as appropriate.
  291. */
  292.  
  293. static void
  294. puterrmsg(msg)
  295.     const char *msg;
  296. {
  297.     /* output the message as usual */
  298.     putmsg(msg, HoldErrs);
  299.  
  300.     /* signal the error */
  301.     Errors++;
  302.     if (msg[0] == '5')
  303.         CurEnv->e_flags |= EF_FATALERRS;
  304. }
  305. /*
  306. **  FMTMSG -- format a message into buffer.
  307. **
  308. **    Parameters:
  309. **        eb -- error buffer to get result.
  310. **        to -- the recipient tag for this message.
  311. **        num -- arpanet error number.
  312. **        en -- the error number to display.
  313. **        fmt -- format of string.
  314. **        args -- varargs pointer
  315. **
  316. **    Returns:
  317. **        none.
  318. **
  319. **    Side Effects:
  320. **        none.
  321. */
  322.  
  323. /*VARARGS5*/
  324. static void
  325. fmtmsg(eb, to, num, eno, fmt, args)
  326.     char *eb;
  327.     const char *to, *num, *fmt;
  328.     int eno;
  329.     va_list args;
  330. {
  331.     char del;
  332.  
  333.     /* output the reply code */
  334.     if (isdigit(fmt[0]) && isdigit(fmt[1]) && isdigit(fmt[2]))
  335.     {
  336.         num = fmt;
  337.         fmt += 4;
  338.     }
  339.     if (num[3] == '-')
  340.         del = '-';
  341.     else
  342.         del = ' ';
  343.     (void) sprintf(eb, "%3.3s%c", num, del);
  344.     eb += 4;
  345.  
  346.     /* output the file name and line number */
  347.     if (FileName != NULL)
  348.     {
  349.         (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
  350.         eb += strlen(eb);
  351.     }
  352.  
  353.     /* output the "to" person */
  354.     if (to != NULL && to[0] != '\0')
  355.     {
  356.         (void) sprintf(eb, "%s... ", to);
  357.         while (*eb != '\0')
  358.             *eb++ &= 0177;
  359.     }
  360.  
  361.     /* output the message */
  362.     (void) vsprintf(eb, fmt, args);
  363.     while (*eb != '\0')
  364.         *eb++ &= 0177;
  365.  
  366.     /* output the error code, if any */
  367.     if (eno != 0)
  368.         (void) sprintf(eb, ": %s", errstring(eno));
  369. }
  370. /*
  371. **  ERRSTRING -- return string description of error code
  372. **
  373. **    Parameters:
  374. **        errno -- the error number to translate
  375. **
  376. **    Returns:
  377. **        A string description of errno.
  378. **
  379. **    Side Effects:
  380. **        none.
  381. */
  382.  
  383. char *
  384. errstring(errno)
  385.     int errno;
  386. {
  387.     extern char *sys_errlist[];
  388.     extern int sys_nerr;
  389.     static char buf[100];
  390. #if defined(DAEMON) && defined(VMUNIX)
  391.     extern char *SmtpPhase;
  392.  
  393.     /*
  394.     **  Handle special network error codes.
  395.     **
  396.     **    These are 4.2/4.3bsd specific; they should be in daemon.c.
  397.     */
  398.  
  399.     switch (errno)
  400.     {
  401.       case ETIMEDOUT:
  402.       case ECONNRESET:
  403.         (void) strcpy(buf, sys_errlist[errno]);
  404.         if (SmtpPhase != NULL)
  405.         {
  406.             (void) strcat(buf, " during ");
  407.             (void) strcat(buf, SmtpPhase);
  408.         }
  409.         if (CurHostName != NULL)
  410.         {
  411.             (void) strcat(buf, " with ");
  412.             (void) strcat(buf, CurHostName);
  413.         }
  414.         return (buf);
  415.  
  416.       case EHOSTDOWN:
  417.         if (CurHostName == NULL)
  418.             break;
  419.         (void) sprintf(buf, "Host %s is down", CurHostName);
  420.         return (buf);
  421.  
  422.       case ECONNREFUSED:
  423.         if (CurHostName == NULL)
  424.             break;
  425.         (void) sprintf(buf, "Connection refused by %s", CurHostName);
  426.         return (buf);
  427.  
  428. # ifdef NAMED_BIND
  429.       case (TRY_AGAIN+MAX_ERRNO):
  430.         (void) sprintf(buf, "Host Name Lookup Failure");
  431.         return (buf);
  432. # endif /* NAMED_BIND */
  433.     }
  434. #endif /* VMUNIX && DAEMON */
  435.  
  436.     if (errno > 0 && errno < sys_nerr)
  437.         return (sys_errlist[errno]);
  438.  
  439.     (void) sprintf(buf, "Error %d", errno);
  440.     return (buf);
  441. }
  442.